package com.tz.pay.weixin.core.common;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

import com.alibaba.fastjson.JSONObject;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.tz.pay.weixin.core.service.UnifiedorderService;
import com.tz.pay.weixin.core.utils.Signature;
import com.tz.pay.weixin.core.utils.XMLParser;
import com.tz.pay.weixin.core.vo.RefundQuery;
import com.tz.pay.weixin.core.vo.Unifiedorder;

/**
 * SDK总入口
 */
public class WXPay {
	
	private static Logger logger = Logger.getLogger(Unifiedorder.class);
	
	/**
     * 初始化SDK依赖的几个关键配置
     * @param key 签名算法需要用到的秘钥
     * @param appID 公众账号ID
     * @param mchID 商户ID
     */
    public WXPay(String appID,String mchID,String key){
        Configure.setKey(key);
        Configure.setAppID(appID);
        Configure.setMchID(mchID);
    }
    
    public static HttpURLConnection createURLConn(String urll) throws IOException {
		URL url = null;
		HttpURLConnection http = null;
		url = new URL(urll);
		http = (HttpURLConnection) url.openConnection();
		http.setRequestMethod("POST");
		http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
		http.setDoOutput(true);
		http.setDoInput(true);
		http.setConnectTimeout(30000);
		http.setReadTimeout(30000);
		http.connect();
		return http;
	}
	
	/**
	 * @param final_request
	 * @param urll
	 * @param parm
	 * @return
	 */
	public JSONObject postUrlJson(String urll, String parm) {
		JSONObject json = null;
		HttpURLConnection http = null;
		try {
			http = createURLConn(urll);
			OutputStream os = http.getOutputStream();
			os.write(parm.getBytes("UTF-8"));// 传入参数
			os.flush();
			os.close();
			InputStream is = http.getInputStream();
			int size = is.available();
			byte[] jsonBytes = new byte[size];
			is.read(jsonBytes);
			String message = new String(jsonBytes, "UTF-8");
			json = JSONObject.parseObject(message);
		} catch (IOException e1) {
			logger.error("转换json失败");
			e1.printStackTrace();
		} finally {
			try {
				http.disconnect();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				logger.error("关闭http连接失败");
				e.printStackTrace();
			}
		}
		return json;
	}
	
	
	/**
	 * @param final_request
	 * @param urll
	 * @param parm
	 * @return
	 */
	public static String postUrlXml(String urll, String parm) {
		HttpURLConnection http = null;
		String message = "";
		logger.info(http);
		try {
			http = createURLConn(urll);
			OutputStream os = http.getOutputStream();
			os.write(parm.getBytes("UTF-8"));// 传入参数
			os.flush();
			os.close();
			InputStream is = http.getInputStream();
			int size = is.available();
			byte[] jsonBytes = new byte[size];
			is.read(jsonBytes);
			message = new String(jsonBytes, "UTF-8");
		} catch (IOException e1) {
			logger.error("转换json失败");
			e1.printStackTrace();
		} finally {
			logger.info("关闭http连接");
			try {
				http.disconnect();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				logger.error("关闭http连接失败");
				e.printStackTrace();
			}
		}
		return message.toString();
	}
    
    /**
     * 请求支付服务
     * @param scanPayReqData 这个数据对象里面包含了API要求提交的各种数据字段
     * @return API返回的数据
     * @throws Exception
     */
    public String requestScanPayService(Unifiedorder unifiedorde) throws Exception {
    	
    	//1.签名方法
    	String sign = Signature.getSign(unifiedorde.toMap());
    	//把签名数据设置到Sign这个属性中
    	unifiedorde.setSign(sign);
    	
    	//2.将签名方法
    	XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));

        //将要提交给API的数据对象转换成XML格式数据Post给API
    	xStreamForRequestPostData.alias("xml", unifiedorde.getClass());
    	xStreamForRequestPostData.ignoreUnknownElements();
    	String postDataXML = xStreamForRequestPostData.toXML(unifiedorde);
    	
    	
    	System.out.println(postDataXML);
    	String result = postUrlXml(ApiURL.unifiedorder, postDataXML);
    	System.out.println(result);
    	
        Map<String,Object> map = XMLParser.getMapFromXML(result);
        
        System.out.println(map.toString());
        
        
        return new UnifiedorderService().request(unifiedorde);
        
    }
    
    /**
	 * 根据微信流水号查询微信订单
	 * 
	 * @param transactionId
	 * @return
	 */
	public Map<String, Object> getPayMsgForTransactionId(RefundQuery orderquery) throws Exception { 
		return getPayMsg(2, orderquery);
	}

	/**
	 * 根据内部订单号查询微信订单
	 * 
	 * @param outTradeNo
	 * @return
	 * @throws Exception 
	 */
	public static Map<String, Object> getPayMsgForOutTradeNo(RefundQuery orderquery) throws Exception { 
		return getPayMsg(1, orderquery);
	}

	/**
	 * 查询微信订单
	 * @param type
	 * @param orderno
	 * @return
	 * @throws SAXException 
	 * @throws IOException 
	 * @throws Exception 
	 */
	private static Map<String, Object> getPayMsg(int type, RefundQuery orderquery) throws Exception { 

		//1.签名方法
    	String sign = Signature.getSign(orderquery.toMap());
    	//把签名数据设置到Sign这个属性中
    	orderquery.setSign(sign);

    	//2.将签名方法
    	XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));

        //将要提交给API的数据对象转换成XML格式数据Post给API
    	xStreamForRequestPostData.alias("xml", orderquery.getClass());
    	xStreamForRequestPostData.ignoreUnknownElements();
    	String postDataXML = xStreamForRequestPostData.toXML(orderquery);
    	System.out.println(postDataXML.toString());
    	
    	
		String resultXml = postUrlXml(ApiURL.refundquery, postDataXML);
		System.out.println(resultXml.toString());

		Map<String, Object> payrel = XMLParser.getMapFromXML(resultXml);
		return payrel;
	}
    
}
